change file_exists_and_is_not_folder checks to get the file info for the
authorKristian Rietveld <kris@imendio.com>
Sun, 3 Sep 2006 20:47:54 +0000 (20:47 +0000)
committerKristian Rietveld <kristian@src.gnome.org>
Sun, 3 Sep 2006 20:47:54 +0000 (20:47 +0000)
2006-09-03  Kristian Rietveld  <kris@imendio.com>

* gtk/gtkfilechooserdefault.c (save_entry_get_info_cb),
(file_exists_get_info_cb), (gtk_file_chooser_default_should_respond):
change file_exists_and_is_not_folder checks to get the file info
for the path directly instead of querying the current file folder
of the save entry.

* gtk/gtkfilechooserprivate.h (struct _GtkFileChooserDefault): add
new field.

* tests/autotestfilechooser.c (wait_for_idle_idle), (wait_for_idle),
(test_reload_sequence), (test_button_folder_states_for_action): wait
for idle after setting a folder to ensure the async operations to load
the folder are finished,
(test_confirm_overwrite), (test_confirm_overwrite_for_path):
factor out test_confirm_overwrite code so we can add tests for more
paths more easily.

ChangeLog
gtk/gtkfilechooserdefault.c
gtk/gtkfilechooserprivate.h
tests/autotestfilechooser.c

index 18791dfc3922015da9b05f94aacd83cdc6fd64fa..a81859c49d6b44ee585e1abd6e68e71bfe8cc591 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,22 @@
+2006-09-03  Kristian Rietveld  <kris@imendio.com>
+
+       * gtk/gtkfilechooserdefault.c (save_entry_get_info_cb),
+       (file_exists_get_info_cb), (gtk_file_chooser_default_should_respond):
+       change file_exists_and_is_not_folder checks to get the file info
+       for the path directly instead of querying the current file folder
+       of the save entry.
+
+       * gtk/gtkfilechooserprivate.h (struct _GtkFileChooserDefault): add
+       new field.
+
+       * tests/autotestfilechooser.c (wait_for_idle_idle), (wait_for_idle),
+       (test_reload_sequence), (test_button_folder_states_for_action): wait
+       for idle after setting a folder to ensure the async operations to load
+       the folder are finished,
+       (test_confirm_overwrite), (test_confirm_overwrite_for_path):
+       factor out test_confirm_overwrite code so we can add tests for more
+       paths more easily.
+
 2006-09-03  Richard Hult  <richard@imendio.com>
 
        * gdk/quartz/GdkQuartzView.c (drawRect): Don't do anything if
index ff7482527cd7e7e65554b89bdadbd49ce02aee9b..6c50ef3c0524d243b41a6f38bd6fd5ac79733d6e 100644 (file)
@@ -7327,7 +7327,7 @@ out:
   g_object_unref (handle);
 }
 
-struct SaveEntryData
+struct FileExistsData
 {
   GtkFileChooserDefault *impl;
   gboolean file_exists_and_is_not_folder;
@@ -7343,7 +7343,7 @@ save_entry_get_info_cb (GtkFileSystemHandle *handle,
 {
   gboolean parent_is_folder;
   gboolean cancelled = handle->cancelled;
-  struct SaveEntryData *data = user_data;
+  struct FileExistsData *data = user_data;
 
   if (handle != data->impl->should_respond_get_info_handle)
     goto out;
@@ -7406,6 +7406,72 @@ out:
   g_object_unref (handle);
 }
 
+static void
+file_exists_get_info_cb (GtkFileSystemHandle *handle,
+                        const GtkFileInfo   *info,
+                        const GError        *error,
+                        gpointer             user_data)
+{
+  gboolean data_ownership_taken = FALSE;
+  gboolean cancelled = handle->cancelled;
+  gboolean file_exists_and_is_not_folder;
+  struct FileExistsData *data = user_data;
+
+  if (handle != data->impl->file_exists_get_info_handle)
+    goto out;
+
+  data->impl->file_exists_get_info_handle = NULL;
+
+  set_busy_cursor (data->impl, FALSE);
+
+  if (cancelled)
+    goto out;
+
+  file_exists_and_is_not_folder = info && !gtk_file_info_get_is_folder (info);
+
+  if (data->impl->action == GTK_FILE_CHOOSER_ACTION_OPEN)
+    /* user typed a filename; we are done */
+    g_signal_emit_by_name (data->impl, "response-requested");
+  else if (data->impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER
+          && file_exists_and_is_not_folder)
+    {
+      /* Oops, the user typed the name of an existing path which is not
+       * a folder
+       */
+      error_creating_folder_over_existing_file_dialog (data->impl, data->path,
+                                                      g_error_copy (error));
+    }
+  else
+    {
+      /* check that everything up to the last component exists */
+
+      data->file_exists_and_is_not_folder = file_exists_and_is_not_folder;
+      data_ownership_taken = TRUE;
+
+      if (data->impl->should_respond_get_info_handle)
+       gtk_file_system_cancel_operation (data->impl->should_respond_get_info_handle);
+
+      data->impl->should_respond_get_info_handle =
+       gtk_file_system_get_info (data->impl->file_system,
+                                 data->parent_path,
+                                 GTK_FILE_INFO_IS_FOLDER,
+                                 save_entry_get_info_cb,
+                                 data);
+      set_busy_cursor (data->impl, TRUE);
+    }
+
+out:
+  if (!data_ownership_taken)
+    {
+      g_object_unref (data->impl);
+      gtk_file_path_free (data->path);
+      gtk_file_path_free (data->parent_path);
+      g_free (data);
+    }
+
+  g_object_unref (handle);
+}
+
 static void
 paste_text_received (GtkClipboard          *clipboard,
                     const gchar           *text,
@@ -7593,46 +7659,26 @@ gtk_file_chooser_default_should_respond (GtkFileChooserEmbed *chooser_embed)
        }
       else
        {
-         gboolean file_exists_and_is_not_folder;
-
-         file_exists_and_is_not_folder = g_error_matches (error, GTK_FILE_SYSTEM_ERROR, GTK_FILE_SYSTEM_ERROR_NOT_FOLDER);
-
-         if (impl->action == GTK_FILE_CHOOSER_ACTION_OPEN)
-           retval = TRUE; /* user typed a filename; we are done */
-         else if (impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER && file_exists_and_is_not_folder)
-           {
-             /* Oops, the user typed the name of an existing path which is not a folder */
-             error_creating_folder_over_existing_file_dialog (impl, path, error);
-             error = NULL; /* as it will be freed below for the general case */
-             retval = FALSE;
-           }
-         else
-           {
-             GtkFilePath *parent_path;
-             struct SaveEntryData *data;
-
-             /* check that everything up to the last component exists */
+         struct FileExistsData *data;
 
-             parent_path = gtk_file_path_copy (_gtk_file_chooser_entry_get_current_folder (entry));
+         /* We need to check whether path exists and is not a folder */
 
-             data = g_new0 (struct SaveEntryData, 1);
-             data->impl = g_object_ref (impl);
-             data->file_exists_and_is_not_folder = file_exists_and_is_not_folder;
-             data->parent_path = parent_path; /* Takes ownership */
-             data->path = gtk_file_path_copy (path);
+         data = g_new0 (struct FileExistsData, 1);
+         data->impl = g_object_ref (impl);
+         data->path = gtk_file_path_copy (path);
+         data->parent_path = gtk_file_path_copy (_gtk_file_chooser_entry_get_current_folder (entry));
 
-             if (impl->should_respond_get_info_handle)
-               gtk_file_system_cancel_operation (impl->should_respond_get_info_handle);
+         if (impl->file_exists_get_info_handle)
+           gtk_file_system_cancel_operation (impl->file_exists_get_info_handle);
 
-             impl->should_respond_get_info_handle =
-               gtk_file_system_get_info (impl->file_system, parent_path,
-                                         GTK_FILE_INFO_IS_FOLDER,
-                                         save_entry_get_info_cb,
-                                         data);
-             set_busy_cursor (impl, TRUE);
+         impl->file_exists_get_info_handle =
+           gtk_file_system_get_info (impl->file_system, path,
+                                     GTK_FILE_INFO_IS_FOLDER,
+                                     file_exists_get_info_cb,
+                                     data);
 
-             retval = FALSE;
-           }
+         set_busy_cursor (impl, TRUE);
+         retval = FALSE;
 
          if (error != NULL)
            g_error_free (error);
index d198e96c272cfb3855ccd7caef4ea2a5552361b2..eb18035c895422335fc09f610b5fbddadddea919 100644 (file)
@@ -206,6 +206,7 @@ struct _GtkFileChooserDefault
   GtkFileSystemHandle *update_current_folder_handle;
   GtkFileSystemHandle *show_and_select_paths_handle;
   GtkFileSystemHandle *should_respond_get_info_handle;
+  GtkFileSystemHandle *file_exists_get_info_handle;
   GtkFileSystemHandle *update_from_entry_handle;
   GtkFileSystemHandle *shortcuts_activate_iter_handle;
   GSList *pending_handles;
index e216fd358a9bcf9551e824082f7ddec052e668da..e7aa8de685097c54f10e416925ebfe93235e96d8 100644 (file)
@@ -77,6 +77,28 @@ set_filename_timeout_cb (gpointer data)
   return FALSE;
 }
 
+
+static guint wait_for_idle_id = 0;
+
+static gboolean
+wait_for_idle_idle (gpointer data)
+{
+  wait_for_idle_id = 0;
+
+  return FALSE;
+}
+
+static void
+wait_for_idle (void)
+{
+  wait_for_idle_id = g_idle_add_full (G_PRIORITY_LOW + 100,
+                                     wait_for_idle_idle,
+                                     NULL, NULL);
+
+  while (wait_for_idle_id)
+    gtk_main_iteration ();
+}
+
 static gboolean
 test_set_filename (GtkFileChooserAction action,
                   gboolean focus_button,
@@ -289,7 +311,7 @@ confirm_overwrite_timeout_cb (gpointer data)
 
 /* http://bugzilla.gnome.org/show_bug.cgi?id=347883 */
 static gboolean
-test_confirm_overwrite (void)
+test_confirm_overwrite_for_path (const char *path)
 {
   gboolean passed;
   struct confirm_overwrite_closure closure;
@@ -308,13 +330,13 @@ test_confirm_overwrite (void)
   g_signal_connect (closure.chooser, "confirm-overwrite",
                    G_CALLBACK (confirm_overwrite_cb), &closure);
 
-  gtk_file_chooser_set_filename (GTK_FILE_CHOOSER (closure.chooser), "/etc/passwd"); /* a file we know will always exist */
+  gtk_file_chooser_set_filename (GTK_FILE_CHOOSER (closure.chooser), path);
 
   g_timeout_add (2000, confirm_overwrite_timeout_cb, &closure);
   gtk_dialog_run (GTK_DIALOG (closure.chooser));
 
   filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (closure.chooser));
-  passed = passed && filename && (strcmp (filename, "/etc/passwd") == 0);
+  passed = passed && filename && (strcmp (filename, path) == 0);
   g_free (filename);
   
   gtk_widget_destroy (closure.chooser);
@@ -326,6 +348,16 @@ test_confirm_overwrite (void)
   return passed;
 }
 
+static gboolean
+test_confirm_overwrite (void)
+{
+  gboolean passed = TRUE;
+
+  passed = passed && test_confirm_overwrite_for_path ("/etc/passwd"); /* a file we know will always exist */
+  
+  return passed;
+}
+
 static const GtkFileChooserAction open_actions[] = {
   GTK_FILE_CHOOSER_ACTION_OPEN,
   GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER
@@ -585,6 +617,8 @@ test_reload_sequence (gboolean set_folder_before_map)
     {
       gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog), g_get_home_dir ());
 
+      wait_for_idle ();
+
       passed = passed && (impl->current_folder != NULL
                          && impl->browse_files_model != NULL
                          && (impl->load_state == LOAD_PRELOAD || impl->load_state == LOAD_LOADING || impl->load_state == LOAD_FINISHED)
@@ -594,6 +628,8 @@ test_reload_sequence (gboolean set_folder_before_map)
                              ? (impl->load_timeout_id == 0 && impl->sort_model != NULL)
                              : TRUE));
 
+      wait_for_idle ();
+
       folder = gtk_file_chooser_get_current_folder (GTK_FILE_CHOOSER (dialog));
       passed = passed && (folder != NULL && strcmp (folder, g_get_home_dir()) == 0);
       g_free (folder);
@@ -608,6 +644,8 @@ test_reload_sequence (gboolean set_folder_before_map)
                          && impl->reload_state == RELOAD_EMPTY
                          && impl->load_timeout_id == 0);
 
+      wait_for_idle ();
+
       folder = gtk_file_chooser_get_current_folder (GTK_FILE_CHOOSER (dialog));
       passed = passed && (folder != NULL && strcmp (folder, current_working_dir) == 0);
     }
@@ -618,6 +656,8 @@ test_reload_sequence (gboolean set_folder_before_map)
 
   gtk_widget_show_now (dialog);
 
+  wait_for_idle ();
+
   passed = passed && (impl->current_folder != NULL
                      && impl->browse_files_model != NULL
                      && (impl->load_state == LOAD_PRELOAD || impl->load_state == LOAD_LOADING || impl->load_state == LOAD_FINISHED)
@@ -641,6 +681,8 @@ test_reload_sequence (gboolean set_folder_before_map)
 
   gtk_widget_hide (dialog);
 
+  wait_for_idle ();
+
   passed = passed && (impl->current_folder != NULL
                      && impl->browse_files_model != NULL
                      && (impl->load_state == LOAD_PRELOAD || impl->load_state == LOAD_LOADING || impl->load_state == LOAD_FINISHED)
@@ -664,6 +706,8 @@ test_reload_sequence (gboolean set_folder_before_map)
 
   gtk_widget_show_now (dialog);
 
+  wait_for_idle ();
+
   passed = passed && (impl->current_folder != NULL
                      && impl->browse_files_model != NULL
                      && (impl->load_state == LOAD_PRELOAD || impl->load_state == LOAD_LOADING || impl->load_state == LOAD_FINISHED)
@@ -743,6 +787,7 @@ test_button_folder_states_for_action (GtkFileChooserAction action, gboolean use_
   gtk_container_add (GTK_CONTAINER (window), button);
 
   /* Pre-map; no folder is set */
+  wait_for_idle ();
 
   folder = gtk_file_chooser_get_current_folder (GTK_FILE_CHOOSER (button));
   if (must_have_cwd)
@@ -760,6 +805,9 @@ test_button_folder_states_for_action (GtkFileChooserAction action, gboolean use_
 
   gtk_widget_show_all (window);
   gtk_widget_show_now (window);
+
+  wait_for_idle ();
+
   folder = gtk_file_chooser_get_current_folder (GTK_FILE_CHOOSER (button));
 
   if (must_have_cwd)
@@ -777,6 +825,7 @@ test_button_folder_states_for_action (GtkFileChooserAction action, gboolean use_
   /* Unmap; folder should be set */
 
   gtk_widget_hide (window);
+  wait_for_idle ();
   folder = gtk_file_chooser_get_current_folder (GTK_FILE_CHOOSER (button));
 
   if (must_have_cwd)
@@ -800,7 +849,7 @@ test_button_folder_states_for_action (GtkFileChooserAction action, gboolean use_
     passed = passed && (folder != NULL && strcmp (folder, current_working_dir) == 0);
   else
     passed = passed && (folder != NULL && strcmp (folder, g_get_home_dir()) == 0);
-
+  wait_for_idle ();
   log_test (passed, "test_button_folder_states_for_action(): %s, use_dialog=%d, set_folder_on_dialog=%d, re-mapped, %s",
            get_action_name (action),
            use_dialog,